/*
 * cpu.h
 *
 *  Created on: Mar 4, 2012
 *		CPU must have reference to Schedule, in order to pass off interrupts.
 *		CPU must have reference to Shared memory, in order to execute STORE and LOAD operations for Programs.
 *		CPU must have reference to ALL processes.
 *
 *
 *      PC:
 *     		Processes MUST be tied to PC in some way (PC for specific programs generated randomly on startup).
 *     			 CPU will use the PC to determine which op to run inside process
 *
 *      	CPU Increments the PC
 *      	PC stored in context switch
 *
 *      Context Switch:
 *      	Stores PC
 *      	data from PCB of running process.
 *
 *      Handles system calls:
 *      	STORE and LOAD from shared memory
 *      	IO Requests (output path)
 *      	access memory
 *
 *      Blocks processes waiting on something ?
 *
 *
 *      handles Interrupts (from I/O devices):
 *      	1) store PCB information from currently running process
 *
 *      	2) handle interrupt from CPU side
 *      		A) find? and change the the state for any blocked process waiting on interrupt from BLOCKED to RUNNABLE
 *      		B) Store input somehow ? (maybe in PCB ? )
 *
 *      	3) restore running process
 *
 */

#ifndef CPU_H_
#define CPU_H_

#include "interrupt.h"
#include "../Scheduler/scheduler.h"
#include "../Shared Memory/memory.h"
#include "../Processes/process.h"
#include "../Utility/queue.h"
#include "../Utility/semaphore.h"
#include "../IO Devices/io_device.h"

typedef struct{

	int PC;
	process * my_active_process;

	scheduler* my_scheduler;
	memory* my_memory;

	Queue my_interrupt_queue;

	semaphore_t* my_semaphores;

	io_device* my_keyboard;
	io_device* my_aux_io;

} cpu;
/*
 *
 */
void cpu_init(cpu* the_cpu, scheduler* task_scheduler, memory* ram, process** processes, int process_count, int request_count,
		Queue the_interrupt_q, io_device* the_keyboard, io_device* the_aux_io );

/**
 * Interrupt Type 0=Keyboard, 1=IO Device, 2=System Timer,
 */
void enqueue_interrupt(cpu* cpu_ptr, interrupt* intr);

void run(cpu* cpu_ptr);

#endif /* CPU_H_ */
